package com.wqnmdb.im.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.result.UpdateResult;
import com.wqnmdb.im.annotation.AvoidRepeatableCommit;
import com.wqnmdb.im.domain.contants.ConstantEnum;
import com.wqnmdb.im.domain.mongo.ImApp;
import com.wqnmdb.im.domain.mongo.ImUser;
import com.wqnmdb.im.netty.data.InitNettyData;
import com.wqnmdb.im.domain.resp.R;
import com.wqnmdb.im.domain.resp.RespUtils;
import com.wqnmdb.im.netty.dispose.impl.AsynAndCacheService;
import com.wqnmdb.im.service.RegisterService;
import com.wqnmdb.im.service.mongo.MongoService;
import com.wqnmdb.im.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


/**
 * 注册服务
 */
@Slf4j
@Service
public class RegisterServiceImpl implements RegisterService {

    @Autowired
    private MongoService mongoService;

    @Autowired
    private InitNettyData initNettyData;

    @Autowired
    private AsynAndCacheService asynAndCacheService;

    /**
     * 注册APP
     */
    @Override
    @AvoidRepeatableCommit
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<R> app(String insertAuth, String appName) {
        //校验身份
        if (!ConstantEnum.AUTH.getContent().equals(insertAuth)){
            return RespUtils.fail("验证未通过");
        }

        JSONObject result = new JSONObject();
        //检查APP名称是否可用
        ImApp checkApp = mongoService.findOne(
                new Query(Criteria.where("name").is(appName)), ImApp.class);
        if (checkApp != null){
            result.put("accessKey", checkApp.getAuth());
            result.put("secretKey", checkApp.getSalt());
            return RespUtils.success(result);
        }
        //注册
        String salt = PBEUtil.initSalt();
        String password = UUIDUtil.genShort();
        String auth = PBEUtil.encryptAndDecrypt(appName, password, salt, 1);
        ImApp app = new ImApp();
        app.setName(appName);
        app.setSalt(salt);
        app.setPassword(password);
        app.setAuth(auth);
        app.setOnLineNum(0);
        app.setStatus(1);
        app.setUpdateTime(DateUtil.getNowInt());
        app.setCreateTime(DateUtil.getNowInt());
        ImApp insertResult = mongoService.insert(app);
        log.info("插入结果：{}.", JSON.toJSONString(insertResult));

        if (insertResult != null){
            //初始化app通道容器
            initNettyData.createChannelContainer(appName);
            result.put("accessKey", auth);
            result.put("secretKey", salt);
            return RespUtils.success(result);
        }
        return RespUtils.fail("创建App失败");
    }

    /**
     * 注册用户
     */
    @Override
    @AvoidRepeatableCommit
    public ResponseEntity<R> user(String accessKey, String secretKey, String os, Integer userId) {
        if (userId <= 0){
            return RespUtils.fail("缺少必要参数");
        }
        ImApp app = mongoService.findOne(new Query(Criteria.where("auth").is(accessKey)
                .and("salt").is(secretKey).and("status").is(1)), ImApp.class);
        if (app == null){
            return RespUtils.fail("应用不存在");
        }
        //校验
        String appName = PBEUtil.encryptAndDecrypt(accessKey, app.getPassword(), secretKey, 2);
        if (!app.getName().equals(appName)){
            return RespUtils.fail("校验未通过");
        }

        JSONObject result = new JSONObject();
        //验证并保存用户
        String collectionName = asynAndCacheService.getUserCollectionName(app.getName());
        ImUser checkUser = mongoService.findOne(
                new Query(Criteria.where("userId").is(userId)), ImUser.class, collectionName);
        if (checkUser == null){
            //注册
            String salt = PBEUtil.initSalt();
            String password = UUIDUtil.genShort();
            String auth = PBEUtil.encryptAndDecrypt(userId.toString(), password, salt, 1);
            ImUser user = new ImUser();
            user.setUserId(userId);
            user.setAppId(app.getId());
            user.setAppName(app.getName());
            user.setIsOnLine(0);
            user.setSalt(salt);
            user.setOs(os);
            user.setPassword(password);
            user.setAuth(auth);
            user.setStatus(1);
            user.setCreateTime(DateUtil.getNowInt());
            user.setUpdateTime(DateUtil.getNowInt());
            mongoService.insert(user, collectionName);

            result.put("accessKey", auth);
            result.put("secretKey", salt);
        }else {
            if (checkUser.getStatus() != 1){
                return RespUtils.fail("用户状态异常");
            }
            //更新OS
            if (!checkUser.getOs().equals(os)){
                UpdateResult updateResult = mongoService.updateFirst(new Query(Criteria.where("id").is(checkUser.getId())),
                        new Update().set("os", os).set("updateTime", DateUtil.getNowInt()), ImUser.class, collectionName);
                log.info("更新终端类型结果：{}.", updateResult.getModifiedCount());
            }
            result.put("accessKey", checkUser.getId());
            result.put("secretKey", checkUser.getSalt());
        }
        return RespUtils.success(result);
    }
}

